﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using MLMBonus.Engine;
using MLMBonus.Unilevel.Properties;

namespace MLMBonus.Unilevel
{
    public class UnilevelContext : IBonusContext
    {
        #region IBonusContext Members

        public void Pay(IVolume Volume, INode Distributor, string Description, int? Level, decimal Amount, decimal? Percent)
        {
            throw new NotImplementedException();
        }

        public void Promote(INode Distributor, string OldRank, string NewRank)
        {
            throw new NotImplementedException();
        }

        #endregion

        public UnilevelContext()
        {
            rankConfig = getRankConfig();
            configureRanks();
        }

        public UnilevelContext(XDocument RankConfig)
        {
            this.rankConfig = RankConfig;
            configureRanks();
        }

        private void configureRanks()
        {
            OrderedRanks = from rank in rankConfig.Descendants("Rank")
                           orderby rank.Attribute("id").Value
                           select rank;
            LowestNonRetailRank = (from rank in OrderedRanks
                                   where rank.Element("IsRetail") == null || rank.Element("IsRetail").Value.Equals("false", StringComparison.InvariantCultureIgnoreCase)
                                   select rank).First();
            UnilevelPayouts = from level in rankConfig.Descendants("Level")
                              select level;
            GenerationPayouts = from gen in rankConfig.Descendants("Generation")
                                select gen;
            FastStartPayouts = from fast in rankConfig.Descendants("FastStartPayout")
                               select fast;
        }

        internal static bool isBreakaway(XElement rank)
        {
            if (rank.Element("IsBreakaway") != null)
            {
                return rank.Element("IsBreakaway").Value.Equals("true", StringComparison.InvariantCultureIgnoreCase);
            }
            return false;
        }

        internal static bool isRetail(XElement rank)
        {
            if (rank.Element("IsRetail") != null)
            {
                return rank.Element("IsRetail").Value.Equals("true", StringComparison.InvariantCultureIgnoreCase);
            }
            return false;
        }

        internal static int maxLevels;
        internal static int maxGens;
        internal XDocument rankConfig { get; set; }
        internal IOrderedEnumerable<XElement> OrderedRanks { get; set; }
        internal XElement LowestNonRetailRank { get; set; }
        internal IEnumerable<XElement> UnilevelPayouts { get; set; }
        internal IEnumerable<XElement> GenerationPayouts { get; set; }
        internal IEnumerable<XElement> FastStartPayouts { get; set; }

        internal decimal getUnilevelPercent(int level)
        {
            if (level <= 0)
            {
                return 0;
            }
            return Convert.ToDecimal((from uni in UnilevelPayouts
                                      where uni.Attribute("ord").Value == level.ToString()
                                      select uni.Value).FirstOrDefault());
        }

        internal decimal getGenerationPercent(int generation)
        {
            return Convert.ToDecimal((from gen in GenerationPayouts
                                      where gen.Attribute("ord").Value == generation.ToString()
                                      select gen.Value).FirstOrDefault());
        }

        internal decimal? getFastStartPercent(int rank)
        {
            var fs = (from fast in FastStartPayouts
                      where rank >= int.Parse(fast.Attribute("qualRank").Value)
                      orderby int.Parse(fast.Attribute("qualRank").Value) descending
                      select fast.Value).FirstOrDefault();

            decimal fsPercent;
            if (decimal.TryParse(fs, out fsPercent))
                return fsPercent;
            return null;
        }

        private XDocument getRankConfig()
        {
            FileInfo rankFile = new FileInfo(Settings.Default.RankConfigFilename);
            if (!rankFile.Exists)
            {
                rankFile = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Settings.Default.RankConfigFilename));
            }
            XDocument ranks = null;
            if (rankFile.Exists)
            {
                ranks = XDocument.Load(rankFile.FullName);
            }
            else
            {
                ranks = XDocument.Parse(Resources.RankConfig);
            }

            maxLevels = Convert.ToInt32((from elem in ranks.Descendants("Level")
                                         select elem.Attribute("ord").Value).Max());

            maxGens = Convert.ToInt32((from elem in ranks.Descendants("Generation")
                                       select elem.Attribute("ord").Value).Max());

            return ranks;
        }
    }
}
